Eric Landes provided the patch (edited by me) that introduces the --keepalive-time to curl to set the keepalive probe interval. I also took the opportunity to rename the recently added no-keep-alive option to no-keepalive to keep a consistent naming and to avoid getting two dashes in these option names. Eric also provided an update to the man page for the new option. 
diff --git a/CHANGES b/CHANGES index 203d946..b249380 100644 --- a/CHANGES +++ b/CHANGES 
@@ -6,6 +6,14 @@    Changelog   +Daniel S (12 Jan 2008) +- Eric Landes provided the patch (edited by me) that introduces the + --keepalive-time to curl to set the keepalive probe interval. I also took + the opportunity to rename the recently added no-keep-alive option to + no-keepalive to keep a consistent naming and to avoid getting two dashes in + these option names. Eric also provided an update to the man page for the new + option. +  Daniel S (11 Jan 2008)  - Daniel Egger made CURLOPT_RANGE work on file:// URLs the very same way it  already worked for FTP:// URLs. 
diff --git a/RELEASE-NOTES b/RELEASE-NOTES index 49f540f..b1d41c1 100644 --- a/RELEASE-NOTES +++ b/RELEASE-NOTES 
@@ -1,7 +1,7 @@  Curl and libcurl 7.18.0    Public curl releases: 103 - Command line options: 125 + Command line options: 126  curl_easy_setopt() options: 150  Public functions in libcurl: 56  Public web site mirrors: 42 @@ -12,12 +12,13 @@    o --data-urlencode  o CURLOPT_PROXY_TRANSFER_MODE - o --no-keep-alive - now curl does connections with keep-alive enabled by + o --no-keepalive - now curl does connections with keep-alive enabled by  default  o --socks4a added (proxy type CURLPROXY_SOCKS4A for libcurl)  o --socks5-hostname added (CURLPROXY_SOCKS5_HOSTNAME for libcurl)  o curl_easy_pause()  o CURLOPT_SEEKFUNCTION and CURLOPT_SEEKDATA + o --keepalive-time    This release includes the following bugfixes:   @@ -72,6 +73,6 @@  Emil Romanus, Alessandro Vesely, Ray Pekowski, Spacen Jasset, Andrew Moise,  Gilles Blanc, David Wright, Vikram Saxena, Mateusz Loskot, Gary Maxwell,  Dmitry Kurochkin, Mohun Biswas, Richard Atterer, Maxim Perenesenko, - Daniel Egger, Jeff Johnson, Nikitinskit Dmitriy, Georg Lippitsch + Daniel Egger, Jeff Johnson, Nikitinskit Dmitriy, Georg Lippitsch, Eric Landes    Thanks! (and sorry if I forgot to mention someone) 
diff --git a/TODO-RELEASE b/TODO-RELEASE index cc6e488..278e1f8 100644 --- a/TODO-RELEASE +++ b/TODO-RELEASE 
@@ -4,9 +4,6 @@  115 - Cleanup debugging messages in test harness, introduced for new minimum  SSH version support for SCP, SFTP and SOCKS tests   -117 - Eric Landes patch for introducing the --tcp-keep* options - http://curl.haxx.se/mail/lib-2008-01/0038.html (review, consider) -  Less likely to go in 7.18.0  ===========================   
diff --git a/docs/curl.1 b/docs/curl.1 index 0babaaa..91aeb00 100644 --- a/docs/curl.1 +++ b/docs/curl.1 
@@ -612,6 +612,14 @@  \fBhttp://curl.haxx.se/docs/sslcerts.html\fP    If this option is used twice, the second time will again disable it. +.IP "--keepalive-time <seconds>" +This option sets the time a connection needs to remain idle before sending +keepalive probes and the time between individual keepalive probes. It is +currently effective on operating systems offering the TCP_KEEPIDLE and +TCP_KEEPINTVL socket options (meaning Linux, recent AIX, HP-UX and more). This +option has no effect if \fI--no-keepalive\fP is used. (Added in 7.18.0) + +If this option is used multiple times, the last occurrence sets the amount.  .IP "--key <key>"  (SSL/SSH) Private key file name. Allows you to provide your private key in this  separate file. @@ -820,11 +828,11 @@  Using this option will disable that buffering.    If this option is used twice, the second will again switch on buffering. -.IP "--no-keep-alive" -Disables the use of keep-alive messages on the TCP connection, as by default +.IP "--no-keepalive" +Disables the use of keepalive messages on the TCP connection, as by default  curl enables them.   -If this option is used twice, the second will again enable keep-alive. +If this option is used twice, the second will again enable keepalive.  .IP "--no-sessionid"  (SSL) Disable curl's use of SSL session-ID caching. By default all transfers  are done using the cache. Note that while nothing ever should get hurt by 
diff --git a/src/main.c b/src/main.c index 7801c34..55a75bb 100644 --- a/src/main.c +++ b/src/main.c 
@@ -104,6 +104,13 @@  #endif  #endif /* CURL_DOES_CONVERSIONS && HAVE_ICONV */   +#ifdef HAVE_NETINET_IN_H +#include <netinet/in.h> /* for IPPROTO_TCP */ +#endif +#ifdef HAVE_NETINET_TCP_H +#include <netinet/tcp.h> /* for TCP_KEEPIDLE, TCP_KEEPINTVL */ +#endif +  /* The last #include file should be: */  #ifdef CURLDEBUG  #ifndef CURLTOOLDEBUG @@ -486,7 +493,9 @@  char *libcurl; /* output libcurl code to this file name */  bool raw;  bool post301; - bool nokeepalive; + bool nokeepalive; /* for keepalive needs */ + long alivetime; +  struct OutStruct *outs;  };   @@ -679,6 +688,7 @@  " -I/--head Show document info only",  " -j/--junk-session-cookies Ignore session cookies read from file (H)",  " --interface <interface> Specify network interface/address to use", + " --keepalive-time <seconds> Interval between keepalive probes",  " --krb <level> Enable kerberos with specified security level (F)",  " -k/--insecure Allow connections to SSL sites without certs (H)",  " -K/--config Specify which config file to read", @@ -697,7 +707,7 @@  " --netrc-optional Use either .netrc or URL; overrides -n",  " --ntlm Use HTTP NTLM authentication (H)",  " -N/--no-buffer Disable buffering of the output stream", - " --no-keep-alive Disable keep-alive use on the connection", + " --no-keepalive Disable keepalive use on the connection",  " --no-sessionid Disable SSL session-ID reusing (SSL)",  " -o/--output <file> Write output to <file> instead of stdout",  " -O/--remote-name Write output to a file named as the remote file", @@ -1444,11 +1454,13 @@  }     -static int set_so_keepalive(void *clientp, curl_socket_t curlfd, - curlsocktype purpose) +static int sockoptcallback(void *clientp, curl_socket_t curlfd, + curlsocktype purpose)  {  struct Configurable *config = (struct Configurable *)clientp; - int onoff = config->nokeepalive ? 0 : 1; + int onoff = 1; /* this callback is only used if we ask for keepalives on the + connection */ + long keepidle = config->alivetime;    switch (purpose) {  case CURLSOCKTYPE_IPCXN: @@ -1459,6 +1471,28 @@  warnf(clientp, "Could not set SO_KEEPALIVE!\n");  return 0;  } + else { + if (config->alivetime) { +#ifdef TCP_KEEPIDLE + if(setsockopt(curlfd, IPPROTO_TCP, TCP_KEEPIDLE, (void *)&keepidle, + sizeof(keepidle)) < 0) { + /* don't abort operation, just issue a warning */ + SET_SOCKERRNO(0); + warnf(clientp, "Could not set TCP_KEEPIDLE!\n"); + return 0; + } +#endif +#ifdef TCP_KEEPINTVL + if(setsockopt(curlfd, IPPROTO_TCP, TCP_KEEPINTVL, (void *)&keepidle, + sizeof(keepidle)) < 0) { + /* don't abort operation, just issue a warning */ + SET_SOCKERRNO(0); + warnf(clientp, "Could not set TCP_KEEPINTVL!\n"); + return 0; + } +#endif + } + }  break;  default:  break; @@ -1555,8 +1589,9 @@  {"$z", "libcurl", TRUE},  {"$#", "raw", FALSE},  {"$0", "post301", FALSE}, - {"$1", "no-keep-alive", FALSE}, - {"$2", "socks5-hostname", TRUE}, + {"$1", "no-keepalive", FALSE}, + {"$2", "socks5-hostname", TRUE}, + {"$3", "keepalive-time", TRUE},    {"0", "http1.0", FALSE},  {"1", "tlsv1", FALSE}, @@ -2024,9 +2059,13 @@  case '0': /* --post301 */  config->post301 ^= TRUE;  break; - case '1': /* --no-keep-alive */ + case '1': /* --no-keepalive */  config->nokeepalive ^= TRUE;  break; + case '3': /* --keepalive-time */ + if(str2num(&config->alivetime, nextarg)) + return PARAM_BAD_NUMERIC; + break;  }  break;  case '#': /* --progress-bar */ @@ -4590,7 +4629,7 @@  /* curl 7.17.1 */  my_setopt(curl, CURLOPT_POST301, config->post301);  if (!config->nokeepalive) { - my_setopt(curl, CURLOPT_SOCKOPTFUNCTION, set_so_keepalive); + my_setopt(curl, CURLOPT_SOCKOPTFUNCTION, sockoptcallback);  my_setopt(curl, CURLOPT_SOCKOPTDATA, config);  }